package com.itheima.aop;

import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import com.itheima.util.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
public class LogAspect {

   @Autowired
   private HttpServletRequest request;

   @Autowired
   private OperateLogMapper operateLogMapper;

   @Around("@annotation(com.itheima.anno.Log)")
   public Object around(ProceedingJoinPoint pjp) throws Throwable{
       log.info("进行增强 对 增删改 记录日志");
       //1:获取操作人---登录的哪个人 -- token--请求头数据--HttpServletRequest
       //  访问的时候 会在spring中 管理 HttpServletRequest对象
       String token = request.getHeader("token");
       Claims claims = JwtUtils.parseJWT(token);
       Integer operateEmpId = (Integer) claims.get("id");
       //2:获取操作时间
       LocalDateTime operateTime = LocalDateTime.now();
       //3:获取 执行方法的全类名
       String className = pjp.getTarget().getClass().getName();
       //4:获取 执行方法名
       String methodName = pjp.getSignature().getName();
       //5:获取方法运行时的参数
       Object[] args = pjp.getArgs();
       String methodParams = Arrays.toString(args);//将数组参数 转换成字符串

       // 执行目标方法
       long start = System.currentTimeMillis();//获取开始时间
       //6:获取执行方法返回值
       Object result = pjp.proceed();//result就是返回值 注意可能是null
       String returnValue = result == null ? "" : result.toString();
                                //返回值是null就填写空  不是null采用toString
       long end = System.currentTimeMillis();//获取结束时间
       //7:获取执行方法时长
       Long costTime = end - start;
       log.info("操作日志：" + operateEmpId + " " + operateTime + " " + className + " " + methodName + " " + methodParams + " " + returnValue + " " + costTime);
       // 创建OperateLog对象
       OperateLog operateLog = new OperateLog();
       //封装数据
       operateLog.setOperateEmpId(operateEmpId);
       operateLog.setOperateTime(operateTime);
       operateLog.setClassName(className);
       operateLog.setMethodName(methodName);
       operateLog.setMethodParams(methodParams);
       operateLog.setReturnValue(returnValue);
       operateLog.setCostTime(costTime);
       //找 mapper存储
       operateLogMapper.insert(operateLog);
       return result;
   }
}
